﻿namespace PugLib
{
    using System;

    public class Singleton<T>
    {
        private readonly Func<T> _constructor;
        private readonly Object _contextLock = new Object();
        private Boolean _initialized;
        private T _value;

        public Singleton(Func<T> constructor)
        {
            _constructor = constructor;
        }

        public T Value
        {
            get
            {
                if (!_initialized)
                {
                    lock (_contextLock)
                    {
                        if (!_initialized)
                        {
                            _value = _constructor();
                            _initialized = true;
                        }
                    }
                }
                return _value;
            }
        }
    }

    public class Singleton<TArgument, TReturn>
    {
        private readonly TArgument _argument;
        private readonly Func<TArgument, TReturn> _constructor;
        private readonly Object _contextLock = new Object();
        private Boolean _initialized;
        private TReturn _value;

        public Singleton(Func<TArgument, TReturn> constructor, TArgument argument)
        {
            _constructor = constructor;
            _argument = argument;
        }

        public TReturn Value
        {
            get
            {
                if (!_initialized)
                {
                    lock (_contextLock)
                    {
                        if (!_initialized)
                        {
                            _value = _constructor(_argument);
                            _initialized = true;
                        }
                    }
                }
                return _value;
            }
        }
    }
}